﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using Extension;
using UnityEditor;
using UnityEditor.Experimental.GraphView;

namespace Assets.Scripts.UI
{
    [Serializable]
    public enum UIPanelType
    {
        NullPanel,
        MainMenuPanel,
        LoadingPanel,
        GamingPanel,
        PausingPanel,
        CalculatingPanel,
        SettingPanel,
        CMDPanel,
        CircleBtnPanel,
    }
    [Serializable]
    public class UIPanel
    {
        public UIPanelType uIPanelType;
        public string uIPanelPath;
    }
    [Serializable]
    public class UIPanelListJson
    {
        public List<UIPanel> panelList;
        public UIPanelListJson()
        {
            panelList = new List<UIPanel>();
        }
    }
    public class UIManager : Singleton<UIManager>
    {
        readonly string panelPrefabPath = Application.dataPath + @"/Resources/UIPanelPrefab";
        readonly string jsonPath = Application.dataPath + @"/Json/UIJson.json";
        private UIPanelListJson panelListJson;
        private Dictionary<UIPanelType, BasePanel> panelDict;
        private Stack<BasePanel> panelStack;
        private Transform canvasTransform;
        private Transform CanvasTransform
        {
            get
            {
                if (canvasTransform == null)
                {
                    canvasTransform = GameObject.Find("Canvas").transform;
                }
                return canvasTransform;
            }
        }
        public UIManager()
        {
            UIPanelInfoSaveInJson();
        }
        public UIPanelListJson ReadJsonFile(string jsonPath)
        {
            if (!File.Exists(jsonPath))
            {
                File.WriteAllText(jsonPath, "");
            }
            UIPanelListJson panelListJson = null;
            if (File.ReadAllText(jsonPath).Length <= 0)
            {
                panelListJson = new UIPanelListJson();
            }
            else
            {
                panelListJson = JsonUtility.FromJson<UIPanelListJson>(File.ReadAllText(jsonPath));
            }
            return panelListJson;
        }
        public void WriteJsonFile(string jsonPath, UIPanelListJson panelListJson)
        {
            string json = JsonUtility.ToJson(panelListJson);
            File.WriteAllText(jsonPath, json);
        }
        public void UIPanelInfoSaveInJson()
        {
            panelListJson = ReadJsonFile(jsonPath);
            DirectoryInfo folder = new DirectoryInfo(panelPrefabPath);
            foreach (FileInfo file in folder.GetFiles("*.prefab"))
            {
                string uIPaneltypeName = file.Name.Replace(".prefab", "");
                UIPanelType type = Enum.Parse<UIPanelType>(uIPaneltypeName);
                string path = @"UIPanelPrefab/" + uIPaneltypeName;
                bool uIPanelExistInList = false;
                UIPanel uIPanel = panelListJson.panelList.SearchPanelByType(type);
                if (uIPanel != null)
                {
                    uIPanel.uIPanelPath = path;
                    uIPanelExistInList = true;
                }
                if (!uIPanelExistInList)
                {
                    uIPanel = new UIPanel
                    {
                        uIPanelType = type,
                        uIPanelPath = path,
                    };
                    panelListJson.panelList.Add(uIPanel);
                }
            }
            WriteJsonFile(jsonPath, panelListJson);
            AssetDatabase.Refresh();
        }
        public BasePanel GetTopPanel()
        {
            if (panelStack == null || panelStack.Count <= 0)
            {
                return null;
            }
            else return panelStack.Peek();
        }
        public BasePanel CheckPanelExist(UIPanelType uIpanelType)
        {
            if (panelDict == null)
            {
                panelDict = new Dictionary<UIPanelType, BasePanel>();
            }
            BasePanel panel = null;
            panelDict.TryGetValue(uIpanelType, out panel);
            return panel;
        }
        public BasePanel GetPanel(UIPanelType uIpanelType)
        {
            if (panelDict == null)
            {
                panelDict = new Dictionary<UIPanelType, BasePanel>();
            }
            BasePanel panel = null;
            panelDict.TryGetValue(uIpanelType, out panel);
            if (panel == null)
            {
                string panelPath = panelListJson.panelList.SearchPanelByType(uIpanelType).uIPanelPath;
                if (panelPath == null)
                {
                    throw new Exception($"找不到UIPanelType: {uIpanelType} 的Prefab!");
                }
                if (Resources.Load(panelPath) == null)
                {
                    throw new Exception($"找不到PanelPath: {panelPath} 的Prefab!");
                }
                GameObject panelGO = GameObject.Instantiate(Resources.Load(panelPath)) as GameObject;
                panelGO.transform.SetParent(CanvasTransform, false);
                panel = panelGO.GetComponent<BasePanel>();
                panelDict.Add(uIpanelType, panel);
                return panel;
            }
            return panel;
        }
        /// <summary>
        /// 推入Panel，会暂停前一个Panel
        /// </summary>
        /// <param name="uIPanelType"></param>
        public void PushPanel(UIPanelType uIPanelType)
        {
            if (panelStack == null)
            {
                panelStack = new Stack<BasePanel>();
            }
            if (panelStack.Count > 0)
            {
                BasePanel topPanel = panelStack.Peek();
                topPanel.OnPause();
            }
            BasePanel panel = GetPanel(uIPanelType);
            panelStack.Push(panel);
            panel.OnEnter();
        }
        /// <summary>
        /// 叠加Panel，不会暂停前一个Panel
        /// </summary>
        /// <param name="uIPanelType"></param>
        public void AddPanel(UIPanelType uIPanelType)
        {
            if (panelStack == null)
            {
                panelStack = new Stack<BasePanel>();
            }
            BasePanel panel = GetPanel(uIPanelType);
            panelStack.Push(panel);
            panel.OnEnter();
        }
        public void PopPanel()
        {
            if (panelStack == null)
            {
                panelStack = new Stack<BasePanel>();
            }
            if (panelStack.Count <= 0) return;
            BasePanel topPanel = panelStack.Pop();
            topPanel.OnExit();
            if (panelStack.Count > 0)
            {
                topPanel = panelStack.Peek();
                topPanel.OnResume();
            }
        }
    }

}